package com.xuyuan.json.jackson.spring;


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuwuzhou
 * @descriptions
 * @date 2023年02月28日
 */
public class FlowRuntimeContext {

    public static final String TRACE_ID = "traceId";
    public static final String sysRspHead = "sysRspHead";
    public static final String sysReqHead = "sysReqHead";
    private static final String EXCEPTION = "exception";
    private static final List<String> TECH_KEY_LIST = Arrays.asList(TRACE_ID, sysRspHead);

    private static final InheritableThreadLocal<FlowRuntimeContext> LOCAL = new InheritableThreadLocal<FlowRuntimeContext>() {
        @Override
        protected FlowRuntimeContext initialValue() {
            return new FlowRuntimeContext();
        }
    };
    private final Map<String, Object> techContext = new HashMap<>();
    private Map<String, Object> busiContext = new HashMap<>();

    public static List<String> getTechKeyList() {
        return TECH_KEY_LIST;
    }

    /**
     * remove context.
     */
    public static void removeContext() {
        LOCAL.remove();
    }

    public static Object getBusiProperty(String key) {
        return LOCAL.get().getBusiContext().get(key);
    }

    public static void putBusiProperty(String key, Object value) {
        LOCAL.get().getBusiContext().put(key, value);
    }

    public static Object getTechProperty(String key) {
        return LOCAL.get().getTechContext().get(key);
    }

    public static boolean containsTechProperty(String key) {
        return LOCAL.get().getTechContext().containsKey(key);
    }

    public static void putTechProperty(String key, String value) {
        LOCAL.get().getTechContext().put(key, value);
    }

    public static void putTechProperty(String key, Object value) {
        LOCAL.get().getTechContext().put(key, value);
    }

    public static void stashException(Exception e) {
        if (!containsTechProperty(EXCEPTION)) {
            putTechProperty(EXCEPTION, e);
        }
    }

    public static boolean hasException() {
        return containsTechProperty(EXCEPTION);
    }

    public static Exception getException() {
        if (containsTechProperty(EXCEPTION)) {
            return (Exception) getTechProperty(EXCEPTION);
        }
        return null;
    }

    public Map<String, Object> getBusiContext() {
        return busiContext;
    }

    public void setBusiContext(Map<String, Object> busiContext) {
        this.busiContext = busiContext;
    }

    private Map<String, Object> getTechContext() {
        return techContext;
    }
}


